<template>
  <div>
    <div class="xIlPaF">
      <div class="qfa7zW">
        <!--左侧 -->
        <div class="css-u7vcqy">
          <div class="css-ca3fc6">
            <!-- 按钮 -->
            <div class="css-xz12h3">
              <button class="css-z2hftj" @click="AddAI">新对话</button>
            </div>
            <!-- 话题 -->
            <div class="css-ukcncl">
              <div
                class="css-1kav8gu"
                v-for="(item, index) in list"
                @click="onTopic(item, index)"
                :key="index"
                :class="{ gCbxc5: index == dataIndex }"
              >
                <img
                  v-if="index !== dataIndex"
                  src="https://img.wilmer.com.cn/admin/2024/3-13/%E5%AF%B9%E8%AF%9D.png"
                  alt
                />
                <img
                  v-else
                  src="https://img.wilmer.com.cn/admin/2024/3-13/%E5%AF%B9%E8%AF%9D%20%281%29.png"
                  alt
                />
                <div class="css-16i8cfi">
                  {{ item.chatName }}
                </div>
                <!-- 删除 -->
                <div class="more css-b8jday">
                  <div class="css-1kzu8wy">
                    <img
                      @click="onDelete(item)"
                      src="https://img.wilmer.com.cn/admin/2024/4-17/%E5%88%A0%E9%99%A4.png"
                      alt
                    />
                  </div>
                  <!-- <div
                    class="css-r6z5ec"
                    style="
                      position: absolute;
                      inset: 0px 0px auto auto;
                      transform: translate(-14px, 37px);
                    "
                  >
                    <button class="css-1g6os2f">删除</button>
                  </div> -->
                </div>
              </div>
            </div>
          </div>
        </div>
        <!-- 右侧 -->
        <div class="css-1n62g87">
          <!-- 标题 -->
          <div class="css-10di8x5">
            <div class="css-he715">
              {{ list.length > 0 ? list[dataIndex].chatName : "" }}
            </div>
          </div>
          <div class="g4yje1">
            <!-- 消息 -->
            <div
              class="x5y2ug"
              @mouseenter="pageMouseEnter($event)"
              @mouseleave="pageMouseLeave($event)"
              ref="scrollBottom"
            >
              <div class="css-1x7bxye">
                <div
                  class="f2vcwt"
                  v-for="(item, index) in newsList"
                  :key="index"
                  :class="{ vcwt: item.type == 'user' }"
                >
                  <!-- 头像 -->
                  <div class="buc9q" :class="{ v5t6b3: item.type == 'user' }">
                    <div class="css-7vt1qf">
                      <img
                        class="chakra-image css-l4nlio"
                        src="https://img.wilmer.com.cn/admin/2024/4-30/Group%2037768.png"
                        alt
                      />
                    </div>
                  </div>
                  <!-- 消息主题 -->
                  <div
                    class="chakra-card"
                    :class="{ r92ifd: item.type == 'user' }"
                  >
                    <vue-markdown
                      v-if="item.type == 'bot'"
                      :source="item.content"
                    ></vue-markdown>
                    <span v-else>{{ item.content }}</span>
                  </div>
                </div>
              </div>
            </div>
            <!-- 输入框 -->
            <div class="css-1yy90g1">
              <div class="footerBtn">
                <el-input
                  type="textarea"
                  placeholder="请输入问题"
                  v-model="textarea"
                  resize="none"
                  autosize
                  @keydown.native="pushKeyword"
                >
                </el-input>
                <button
                  class="sendBox"
                  :class="{ IqKDO6: !textarea }"
                  @click="onclick()"
                >
                  <img
                    src="https://img.wilmer.com.cn/admin/2024/4-24/%E5%8F%91%E9%80%81%402x.png"
                    alt=""
                  />
                </button>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import VueMarkdown from "vue-markdown";
import {
  userchat,
  AddUserchat,
  aiUserMsg,
  aiUserMsgPut,aiUserMsgDelete
} from "@/api/CAI/index";
import { fetchEventSource } from "@microsoft/fetch-event-source";
import { getToken } from "@/utils/auth";
export default {
  components: {
    VueMarkdown,
  },
  data() {
    return {
      list: [],
      dataIndex: 0,
      chatId: "",
      textarea: "",
      newsList: [], // 消息列表

      RepeatedState: false, // 防止重复提交
      operation: null,
    };
  },
  created() {
    this.getList();
  },
  methods: {
    // 鼠标移入显示 y轴 滚动条
    pageMouseEnter(e) {
      e.target.style.overflowY = "visible";
    },
    // 鼠标移出隐藏 y轴 滚动条
    pageMouseLeave(e) {
      e.target.style.overflowY = "hidden";
    },
    // 滚动条自动滚动到底部
    scrollBottom() {
      this.$nextTick(() => {
        this.$refs.scrollBottom.scroll({
          top:
            this.$refs.scrollBottom.scrollHeight -
            this.$refs.scrollBottom.clientHeight,
          behavior: "smooth",
        });
      });
    },
    // 查询会话列表
    getList() {
      userchat().then((response) => {
        this.list = response.rows;
        if (this.list.length > 0) {
          this.chatId = response.rows[0].chatId;
          this.dataIndex = 0
          this.getHistory();
        } else {
          this.AddAI();
        }
      });
    },
    // 切换话题
    onTopic(item, index) {
      this.dataIndex = index;
      this.chatId = item.chatId;

      this.getHistory();
      this.textarea = "";
    },
    // 查询会话历史记录
    getHistory() {
      aiUserMsg({
        pageNum: 1,
        pageSize: 10000,
        chatId: this.chatId,
      }).then((res) => {
        let arr = [];
        for (let i = 0; i < res.rows.length; i++) {
          console.log(JSON.parse(res.rows[i].msgContext));
          arr.push({
            content: JSON.parse(res.rows[i].msgContext).content,
            type:
              JSON.parse(res.rows[i].msgContext).role == "assistant"
                ? "bot"
                : "user",
          });
        }
        this.newsList = arr;
        this.scrollBottom();
      });
    },
    // 新建AI会话
    AddAI() {
      let that = this;
      AddUserchat({ chatName: "新对话" }).then((res) => {
        userchat().then((response) => {
          that.list = response.rows;
          that.chatId = response.rows[that.list.length - 1].chatId;
          that.getHistory();
        });
      });
    },
    // 发送消息
    onclick() {
      if (this.RepeatedState) {
        return false;
      }
      this.RepeatedState = true;

      let that = this;
      let obj = {
        msg: this.textarea,
        chatId: this.chatId,
      };
      this.newsList.push({
        content: this.textarea,
        type: "user",
      });
      this.newsList.push({
        content: "",
        type: "bot",
      });
      this.scrollBottom();
      this.NameAiUserMsgPut();
      this.textarea = "";

      const controller = new AbortController();
      const signal = controller.signal;
      fetchEventSource(process.env.VUE_APP_BASE_API + `/ai/chat`, {
        method: "POST",
        signal: signal,
        headers: {
          "Content-Type": "application/json",
          Authorization: "Bearer " + getToken(), // 让每个请求携带自定义token 请根据实际情况自行修改
        },
        body: JSON.stringify(obj),
        onmessage(msg) {
          let detail = JSON.parse(msg.data);
          if (detail.event === "") {
          } else if (detail.event === "close" || detail.event === "stop") {
            that.RepeatedState = false;
            controller.abort();
          }
          that.newsList[that.newsList.length - 1].content += detail.content;
          that.scrollBottom();
        },
        onerror(err) {
          that.RepeatedState = false;
          throw err; // 或者throw改为其他
        },
      });
    },
    // 回车事件
    pushKeyword(event) {
      if (event.keyCode == 13) {
        event.preventDefault(); // 阻止浏览器默认换行操作
        this.onclick();
        event.target.blur(); // 回车失去焦点
      }
    },
    NameAiUserMsgPut() {
      aiUserMsgPut({
        chatId: this.chatId,
        chatName: this.newsList[this.newsList.length - 2].content,
      }).then((res) => {
        userchat().then((response) => {
          this.list = response.rows;
        });
      });
    },
    // 删除会话
    onDelete(row) {
      const msgIds = row.chatId ;
      this.$modal.confirm('是否确认删除对话信息编号为"' + msgIds + '"的数据项？').then(function() {
        return aiUserMsgDelete(msgIds);
      }).then(() => {
        this.getList();
        this.$modal.msgSuccess("删除成功");
      }).catch(() => {});
    },
  },
};
</script>

<style lang="scss" scoped>
/* 如果你的 el-input type 设置成textarea ，就要用这个了 */
::v-deep .footerBtn .el-textarea__inner {
  border: 0;
  resize: none;
}

::v-deep p {
  margin: 0;
}

.xIlPaF {
  width: 100%;
  min-height: calc(100vh - 84px);
  padding: 20px;
  overflow: hidden;
  position: relative;
  z-index: 99;
  display: flex;
  box-sizing: border-box;
}

.xIlPaF .qfa7zW {overflow: hidden;
  display: flex;
  background: #fff;
  border-radius: 30px;
  box-shadow: 0 12px 50px 26px rgba(0, 0, 0, 0.03);
  box-sizing: border-box;
  flex-grow: 1;
  max-height: calc(var(--100vh) - 40px);

  .wasolt {
    width: calc(100% - 40px);
    max-width: 590px;

    max-height: calc(100vh - 250px);
    height: calc(100vh - 250px);
    overflow-x: visible;
    overflow-y: scroll;
    padding: 20px 0 120px 0;
    scrollbar-width: none;

    .item {
      border-radius: 20px;
      padding: 21px 24px;

      img {
        width: 20px;
        height: 20px;
      }

      .usable__root {
        width: 30px;
        height: 30px;
        min-width: 30px;
        min-height: 30px;
        border-radius: 50%;
        overflow: hidden;
        margin-right: 10px;

        img {
          width: 30px;
          height: 30px;
        }
      }

      span {
        word-wrap: break-word;
      }
    }

    .MDCzlq {
      display: flex;
      align-items: flex-start;
    }

    .X05sUq {
      background: #f8f8fa;
      display: flex;
      align-items: flex-start;
    }
  }
}

.qfa7zW .css-rqs712 {
  position: relative;
  height: 100%;
  overflow: visible;
}

.qfa7zW .css-u7vcqy {
  flex: 0 0 310px;
  border-right: 1px solid rgb(223, 226, 234);
}

.css-ca3fc6 {
  display: flex;
  position: relative;
  flex-direction: column;
  width: 100%;
  height: 100%;
  background: #ffffff;
  //   white-space: nowrap;
}

.qfa7zW .css-u7vcqy .css-xz12h3 {
  height: 36px;
  padding: 0 20px;
  margin: 17.5px 0;

  .css-z2hftj {
    cursor: pointer;
    padding-inline: 20px;
    padding-top: 0px;
    padding-bottom: 0px;
    border-width: 1px;
    border-style: solid;
    border-image: initial;
    transition: background 0.1s ease 0s;
    box-shadow: rgba(19, 51, 107, 0.08) 0px 0px 1px 0px,
      rgba(19, 51, 107, 0.05) 0px 1px 2px 0px;
    flex: 1 1 0%;
    height: 100%;

    display: inline-flex;
    appearance: none;
    align-items: center;
    -webkit-box-pack: center;
    justify-content: center;
    user-select: none;
    position: relative;
    white-space: nowrap;
    vertical-align: middle;
    outline: transparent solid 2px;
    outline-offset: 2px;
    line-height: 1.2;

    border-radius: 16px;
    overflow: hidden;
    font-size: 14px;
    font-weight: 400;
    width: 100%;
    transition: background 0.1s ease 0s;
    background: #ffffff;
    border-color: #dfe2ea;
    color: #3370ff;
  }

  .css-z2hftj:hover {
    color: #3370ff;
    background: rgba(51, 112, 255, 0.1);
    border-color: #94b5ff;
  }
}

.qfa7zW .css-u7vcqy .css-ukcncl {
  flex: 1 0 0px;
  height: 0px;
  overflow: overlay;

  .css-1kav8gu {
    display: flex;
    position: relative;
    -webkit-box-align: center;
    align-items: center;
    padding-top: 10px;
    padding-bottom: 10px;
    padding-inline-start: 14px;
    padding-inline-end: 14px;
    cursor: pointer;
    user-select: none;
    border-radius: 8px;
    margin-bottom: 7px;

    img {
      width: 16px;
      height: 16px;
    }

    .css-16i8cfi {
      flex: 1 0 0px;
      margin-left: 10px;
      text-overflow: ellipsis;
      overflow: hidden; //超出的文本隐藏
      text-overflow: ellipsis; //溢出用省略号显示
      white-space: nowrap; //溢出不换行
    }
  }

  .css-1kav8gu:hover {
    background: #f4f4f7;

    .css-b8jday .css-1kzu8wy img {
      opacity: 1;
    }
  }

  .gCbxc5 {
    color: #3370ff;
    background-color: #f0f4ff !important;
  }

  .css-1kzu8wy {
    width: 21px;
    height: 21px;
    border-radius: 8px;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;

    img {
      opacity: 0;
    }
  }

  .css-r6z5ec {
    visibility: hidden;
    outline: transparent solid 2px;
    outline-offset: 2px;
    padding-top: 4px;
    padding-bottom: 4px;
    z-index: 1;
    border-radius: 8px;
    border-width: 1px;
    background: #fff;
    box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
    color: #383f50;
    min-width: 90px !important;
    border: 1px solid #e2e8f0;

    .css-1g6os2f {
      border-width: 0;
      cursor: pointer;

      text-decoration: none;
      color: inherit;
      user-select: none;
      display: flex;
      width: 100%;
      -webkit-box-align: center;
      align-items: center;
      text-align: start;
      flex: 0 0 auto;
      outline: transparent solid 2px;
      outline-offset: 2px;

      padding-top: 5px;
      padding-bottom: 5px;
      padding-inline-start: 10px;
      padding-inline-end: 10px;

      transition-property: background-color, background-image,
        background-position;
      transition-duration: 50ms;
      transition-timing-function: cubic-bezier(0.4, 0, 1, 1);
      background: #fff;
    }
    .css-1g6os2f:hover {
      color: #f04438;
    }
  }

  .css-1kzu8wy:hover {
    background: #ffffff;
  }
}

@media screen and (min-width: 900px) {
  .css-ukcncl {
    padding-inline-start: 20px;
    padding-inline-end: 20px;
  }
}

@media screen and (min-width: 1500px) {
  .css-u7vcqy {
    flex: 0 0 290px;
  }
}

@media screen and (min-width: 1200px) {
  .css-u7vcqy {
    flex: 0 0 270px;
  }
}

@media screen and (min-width: 900px) {
  .css-u7vcqy {
    flex: 0 0 250px;
    width: 0%;
  }
}

.qfa7zW .css-1n62g87 {
  display: flex;
  position: relative;
  flex: 1 0 0px;
  flex-direction: column;
}

@media screen and (min-width: 900px) {
  .css-1n62g87 {
    height: 100%;
    width: 0%;
  }
}

.qfa7zW .css-1n62g87 .css-10di8x5 {
  display: flex;
  -webkit-box-align: center;
  align-items: center;
  padding: 0 17.5px;
  height: 46px;
  border-bottom: 1px solid rgb(232, 235, 240);
  color: #111824;

  .css-he715 {
  }
}

.footerBtn {
  padding-top: 14px;
  padding-bottom: 14px;
  position: relative;
  box-shadow: rgba(0, 0, 0, 0.2) 0px 0px 10px;
  border-radius: 8px;
  background: #ffffff;
  overflow: hidden;
  border: 1px solid rgba(0, 0, 0, 0.12);
}

.sendBox {
  position: absolute;
  cursor: pointer;
  right: 8px;
  transition: opacity 0.2s ease-in-out !important;
  width: 40px !important;
  height: 40px !important;
  background: linear-gradient(266.44deg, #5ff2cf -28.21%, #0e53fd);
  border: none !important;
  border-radius: 15px !important;
  bottom: 14px;

  img {
    width: 20px;
    height: 20px;
  }
}

.IqKDO6 {
  background: rgb(229, 229, 229) !important;
}

@media screen and (min-width: 900px) {
  .footerBtn {
    padding-top: 18px;
    padding-bottom: 18px;
    border-radius: 8px;
  }
}

.css-1yy90g1 {
  margin: 0px auto;
  width: 100%;
  padding-inline: 0px;
}

@media screen and (min-width: 900px) {
  .css-1yy90g1 {
    margin: 10px auto;
    max-width: min(800px, 100%);
    padding-inline-start: 17.5px;
    padding-inline-end: 17.5px;
  }
}

.g4yje1 {
  display: flex;
  flex-direction: column;
  height: 100%;
}

// 消息
.x5y2ug {
  flex: 1 0 0px;
  height: 0px;
  width: 100%;
  overflow: overlay;
  padding-inline-start: 10px;
  padding-inline-end: 10px;
  padding-bottom: 10px;
}

@media screen and (min-width: 900px) {
  .x5y2ug {
    padding-inline: 0px;
  }
}

.css-1x7bxye {
  max-width: 100%;
  height: 100%;
  margin-inline: auto;

  .f2vcwt {
    width: 100%;
    padding-top: 17.5px;
    padding-bottom: 17.5px;

    .buc9q {
      display: flex;
      width: 100%;
      align-items: center;

      .css-7vt1qf {
        width: 28px;
        height: 28px;
        padding: 2px;
        border-radius: 6px;
        border: 1px solid rgb(223, 226, 234);
        box-shadow: rgba(0, 0, 0, 0.1) 0px 0px 5px;
        background: #f0f4ff;

        .css-l4nlio {
          object-fit: contain;
          border-radius: 8px;
          width: 100%;
          height: 100%;
          padding: 1px;
        }
      }
    }

    .v5t6b3 {
      display: flex;
      width: 100%;
      align-items: center;
      justify-content: flex-end;
    }

    .chakra-card {
      margin-top: 6px;
      flex-direction: column;
      position: relative;
      min-width: 0px;
      overflow-wrap: break-word;

      background: #ffffff;
      padding-inline-start: 14px;
      padding-inline-end: 14px;
      padding-top: 10px;
      padding-bottom: 10px;

      border-radius: 0px 8px 8px;
      box-shadow: rgba(0, 0, 0, 0.15) 0px 0px 8px;
      display: inline-block;
      max-width: calc(100% - 25px);
    }

    .r92ifd {
      flex-direction: column;
      position: relative;
      min-width: 0px;
      overflow-wrap: break-word;

      padding-inline-start: 14px;
      padding-inline-end: 14px;
      padding-top: 10px;
      padding-bottom: 10px;

      border-radius: 8px 0px 8px 8px;
      box-shadow: rgba(0, 0, 0, 0.15) 0px 0px 8px;
      display: inline-block;
      max-width: calc(100% - 25px);
      background: #c5d7ff;
      text-align: left;
    }
  }

  .vcwt {
    text-align: right;
  }
}

@media screen and (min-width: 900px) {
  .css-7vt1qf {
    width: 34px;
    height: 34px;
  }
}

@media screen and (min-width: 900px) {
  .css-1x7bxye {
    max-width: 92%;
  }
}
</style>
